package com.xuanwoa.rabbit.delay.controller;

import com.alibaba.fastjson.JSON;
import com.xuanwoa.rabbit.domain.RabbitSetupBO;
import org.springframework.amqp.rabbit.listener.MessageListenerContainer;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Description
 *
 * @author: caomin
 * @since: 2020/11/17
 */
@RestController
@RequestMapping("rabbit")
public class RabbitConfigController {
    @Resource
    private RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry;

    @RequestMapping("stop")
    public String stop(String id) {
        MessageListenerContainer listenerContainer = rabbitListenerEndpointRegistry.getListenerContainer(id);
        if (listenerContainer.isRunning()) {
            listenerContainer.stop();
            return "stop success";
        }
        return "nothing to do";
    }

    @RequestMapping("start")
    public String start(String id) {
        MessageListenerContainer listenerContainer = rabbitListenerEndpointRegistry.getListenerContainer(id);
        if (!listenerContainer.isRunning()) {
            listenerContainer.start();
            return "start success";
        }

        return "nothing to do";
    }

    @RequestMapping("setup")
    public String setup(int prefetch, int consumer, int maxConsumer) {
        Set<String> containerIds = rabbitListenerEndpointRegistry.getListenerContainerIds();
        SimpleMessageListenerContainer container = null;
        for (String id : containerIds) {
            container = (SimpleMessageListenerContainer) rabbitListenerEndpointRegistry.getListenerContainer(id);
            if (container != null) {
                container.setPrefetchCount(prefetch);
                container.setConcurrentConsumers(consumer);
                container.setMaxConcurrentConsumers(maxConsumer);
            }
        }
        return "ok";
    }


    @RequestMapping("list")
    public String list() {
        //TODO 停用的容器是否能够获取到？
        Collection<MessageListenerContainer> containers = rabbitListenerEndpointRegistry.getListenerContainers();
        if (containers.isEmpty()) {
            return "";
        }
        List<RabbitSetupBO> list = containers.stream().map(e -> {
            SimpleMessageListenerContainer container = (SimpleMessageListenerContainer) e;
            RabbitSetupBO bo = new RabbitSetupBO();
            bo.setId(container.getListenerId());
            bo.setActive(container.isActive());
            Integer prefetchCount = null;
            Integer consumer = null;
            Integer maxConsumer = null;
            try {
                Class<? extends SimpleMessageListenerContainer> aClass = container.getClass();
                Field prefetchCountField = aClass.getSuperclass().getDeclaredField("prefetchCount");
                Field consumerField = aClass.getDeclaredField("concurrentConsumers");
                Field maxConsumersField = aClass.getDeclaredField("maxConcurrentConsumers");

                prefetchCountField.setAccessible(true);
                prefetchCount = (Integer) prefetchCountField.get(container);

                consumerField.setAccessible(true);
                consumer = (Integer) consumerField.get(container);

                maxConsumersField.setAccessible(true);
                maxConsumer = (Integer) maxConsumersField.get(container);
            } catch (NoSuchFieldException | IllegalAccessException noSuchFieldException) {
                noSuchFieldException.printStackTrace();
            }


            bo.setPrefetchCount(prefetchCount);
            bo.setConsumer(consumer);
            bo.setMaxConsumer(maxConsumer);
//            bo.setName();
            return bo;
        }).collect(Collectors.toList());


        return JSON.toJSONString(list);

    }

}
